<route lang="json5" type="page">
{
  layout: 'default',
  style: {
    navigationBarTitleText: '确认订单',
    backgroundColor: '#f5f5f5',
  },
}
</route>

<script setup lang="ts">
import { ref, computed, onUnmounted, onMounted, defineAsyncComponent } from 'vue'
import { getAddressDefault } from '@/service/user/address'
import type { CustomAddressVo } from '@/service/user/address.d'
import { useActiveCartStore } from '@/store/activeCart'
import { getCartListByIds, deleteCartBatch, deleteCart } from '@/service/goods/cart/cart'
import type { GoodsSkuCartVo } from '@/service/goods/cart/cart.d'
import { calculateBestDiscount, autoReceiveCoupon } from '@/service/goods/coupon/coupon'
import type { GoodsDiscountVO, CartItems } from '@/service/goods/coupon/coupon.d'
import { OrderApi } from '@/service/order/order'
import { OrderOperateDto, OrderItemDto } from '@/service/order/order.d'

import { PayApi } from '@/service/pay/pay'
import { createDebounceFunc, formatMoney } from '@/utils/index'
import { useActiveAddressStore } from '@/store/activeAddress'
import { v4 as uuidv4 } from 'uuid'
import { PayTypeEnum } from '@/service/order/orderEnum.d'
import { useUserStore } from '@/store/user'
const AddressPicker = defineAsyncComponent(
  () => import('@/components/address/AddressSelector/AddressSelector.vue'),
)
const PayMent = defineAsyncComponent(() => import('@/components/payment/index.vue'))
const CartBar = defineAsyncComponent(() => import('@/components/cartBar/index.vue'))
const isNowBuy = ref(false)

const activeAddress = useActiveAddressStore()
const activeCartStore = useActiveCartStore()
const userStore = useUserStore()
let timer = null
const cartBarShow = ref(true)

onUnmounted(() => {
  clearTimeout(timer)
  // 清除立即购买的缓存数据
  deleteCart(activeCartStore.temporaryCart.id)
  activeAddress.removeAddress()
  activeCartStore.clearTemporaryCart()
})
onLoad((options) => {
  console.log('options', options)
  if (options.now) {
    isNowBuy.value = true
  }
  if (activeCartStore.cartItems.length <= 0 && !isNowBuy.value) {
    uni.showToast({
      title: '请先选购商品',
      icon: 'none',
      mask: true,
    })
    timer = setTimeout(() => {
      uni.navigateBack()
    }, 200)
  }
})
const getCartListData = async () => {
  let clist = activeCartStore.cartItems
  if (isNowBuy.value) clist = [activeCartStore.temporaryCart]
  console.log('clist', clist)
  const cids = clist.map((item) => {
    return item.id
  })
  try {
    const { code, data } = await getCartListByIds(cids)
    if (code === 200 && data) {
      console.log('获取成功', data)
      goodsList.value = data.records
    } else {
      throw new Error('加载失败')
    }
  } catch (error) {
    uni.showToast({})
  }
}
onMounted(() => {
  getCartListData()
  getGoodsDiscount()
  getAddressDefaultData()
})

const discountList = ref([])
const getGoodsDiscount = async () => {
  let clist = activeCartStore.cartItems
  if (isNowBuy.value) clist = [activeCartStore.temporaryCart]
  console.log('clist', clist)
  if (clist.length <= 0) return

  const cartItems: CartItems[] = clist.map((item) => {
    return {
      skuId: item.skuId,
      quantity: item.goodsNum,
    }
  })
  try {
    const { code, data } = await calculateBestDiscount({
      userId: Number(userStore.userInfo.id),
      cartItems,
    })
    if (code === 200 && data) {
      discountList.value = data
    }
  } catch (error) {}
}

//
const goodsList = ref<GoodsSkuCartVo[]>([])
const requestId = ref(uuidv4().replaceAll('-', '') + Date.now())
const showAll = ref(false)
const paymentType = ref<PayTypeEnum>(PayTypeEnum.ALIPAY)
const remark = ref('')
const defaultAddress = ref<CustomAddressVo>()

// 总金额
const totalPrice = computed<number>(() => {
  return discountList.value.reduce((acc: number, item: GoodsDiscountVO) => {
    // 防御性类型校验
    const quantity = Number(item.quantity) || 0
    const originalPrice = Number(item.originalPrice) || 0
    const discount = Number(item.discountAmount) || 0

    // 精确计算（放大100倍处理小数）
    const base = Math.round(originalPrice * quantity * 100)
    const discountVal = Math.round(discount * 100)
    return acc + (base - discountVal) / 100
  }, 0)
})

// 原价
const marketTotalPrice = computed<number>(() => {
  return discountList.value.reduce((acc: number, cur: GoodsDiscountVO) => {
    const price = cur.marketPrice // 优先取市场价
    return acc + price * cur.quantity
  }, 0)
})
// 促销价
const originalTotalPrice = computed<number>(() => {
  return discountList.value.reduce((acc: number, cur: GoodsDiscountVO) => {
    const price = cur.originalPrice // 优先取市场价
    return acc + price * cur.quantity
  }, 0)
})
const discountTotalPrice = computed<number>(() => {
  return discountList.value.reduce((acc: number, cur: GoodsDiscountVO) => {
    const itemPrice = Number(cur.discountAmount) || 0 // 优先取市场价
    // 优先取市场价
    return acc + itemPrice
  }, 0)
})
//使用的优惠卷id
const useCouponIds = computed<number[]>(() => {
  let li = []
  if (discountList.value && discountList.value.length > 0) {
    discountList.value.forEach((item) => {
      if (item.usedCoupon) {
        item.usedCoupon.id && li.push(item.usedCoupon.id)
      }
    })
  }

  return li
})

// 获取默认地址
const getAddressDefaultData = async () => {
  console.log(activeAddress.addressData)
  console.log(userStore.userInfo)

  if (activeAddress.addressData) {
    defaultAddress.value = activeAddress.addressData
    return
  }
  const { code, data } = await getAddressDefault()
  if (code === 200 && data) {
    defaultAddress.value = data
  }
}

// 提交订单
const addOrder = async () => {
  console.log('useCouponIds:', useCouponIds.value)
  if (useCouponIds.value && useCouponIds.value.length > 0) {
    const { code, data } = await autoReceiveCoupon({
      userId: userStore.userInfo.id,
      couponIds: useCouponIds.value,
    })
    if (code === 200 && data) {
      uni.showToast({ title: '已自动领取优惠卷', icon: 'none' })
    }
  }
  uni.showLoading({ title: '提交中...' })
  console.log('提交订单', goodsList.value)

  console.log(defaultAddress.value)
  const orderData: OrderOperateDto = {
    customId: userStore.userInfo.id,
    nickName: userStore.userInfo.nickname,
    receiverAddress: defaultAddress.value.address,
    receiverCity: defaultAddress.value.cityName,
    receiverPhone: defaultAddress.value.phone,
    receiverProvince: defaultAddress.value.provinceName,
    receiverDistrict: defaultAddress.value.districtName,
    receiverName: defaultAddress.value.name,
    receiverTagName: defaultAddress.value.tagName,
    remark: remark.value,
    payType: paymentType.value,
    requestId: requestId.value,
    orderList: [],
  }
  const ids: number[] = goodsList.value
    .filter((item) => item.cartId != null)
    .map((item) => {
      return item.cartId
    })
  goodsList.value.forEach((item) => {
    const orderItem: OrderItemDto = {
      skuId: item.id,
      skuNum: item.goodsNum,
      skuMarketPrice: item.marketPrice,
      skuCode: item.skuCode,
      skuPrice: item.salePrice,
      goodsId: item.goodsId,
      thumbImg: item.thumbImg,
      skuName: item.skuName,
    }
    orderData.orderList.push(orderItem)
  })
  console.log(paymentType.value)

  console.log('提交订单数据', orderData)
  try {
    // 前置校验
    const errorMsg = validateOrderData(orderData)
    if (errorMsg) {
      return uni.showToast({ title: errorMsg, icon: 'none' })
    }

    uni.showLoading({ title: '提交中...' })

    const { code, data } = await OrderApi.createOrder(orderData)
    if (code === 200 && data) {
      uni.hideLoading()
      // 清空购物车
      switch (paymentType.value) {
        case PayTypeEnum.ALIPAY:
          // 调起支付
          PayApi.aliPay(data)
            .then((res) => {
              document.querySelector('body').innerHTML = res as unknown as string
              document.forms[0].submit()
            })
            .catch(() => {
              uni.showToast({ title: '支付失败，请重试', icon: 'none' })
            })
          break
        case PayTypeEnum.BALANCE:
          uni.navigateTo({ url: `/pages/pay/balancePay?orderNo=${data}` })
          break

        default:
          uni.showToast({ title: '暂不支持该支付方式', icon: 'none' })
      }
    } else {
      throw new Error()
    }
  } catch (err) {
    uni.hideLoading()
    uni.showToast({ title: '提交失败，请重试', icon: 'none' })
  } finally {
    deleteCartBatch(ids)
    activeCartStore.removeCartItemIds(ids)
  }
}
const { execute } = createDebounceFunc(addOrder, 1000, {
  leading: true,
  trailing: false,
})
const handleSubmit = async () => {
  execute()
}
// 订单校验
const validateOrderData = (orderData: OrderOperateDto): string | null => {
  // 基础信息校验
  if (!orderData.customId) return '用户身份信息异常'
  if (!orderData.receiverName?.trim()) return '收件人姓名不能为空'

  // 地址组合校验
  const addressComponents = [
    orderData.receiverProvince,
    orderData.receiverCity,
    orderData.receiverDistrict,
    orderData.receiverAddress,
  ]
  if (addressComponents.some((c) => !c?.trim())) {
    return '地址信息不完整'
  }

  // 手机号格式校验
  const phoneReg = /^1[3-9]\d{9}$/
  if (!phoneReg.test(orderData.receiverPhone)) {
    return '手机号格式不正确'
  }

  // 订单项校验
  if (!orderData.orderList?.length) return '请选择要购买的商品'
  for (const item of orderData.orderList) {
    if (!item.skuId) return `商品${item.skuName}信息异常`
    if (item.skuNum < 1) return `商品${item.skuName}数量无效`
    if (Number(item.skuPrice) <= 0) return '存在无效的商品价格'
  }

  return null
}

const goGoodsInfo = (goodsId: number, skuId: number) => {
  uni.navigateTo({
    url: '/pages/goods/info-index',
  })
}

const addressPicker = ref()
const openAddressPicker = () => {
  cartBarShow.value = false
  addressPicker.value.handleOpen()
}
const colseAddress = () => {
  cartBarShow.value = true
}

const onAddressSelect = (address: CustomAddressVo) => {
  console.log('选中的地址:', address)
  defaultAddress.value = address
}

const updatePayment = (e) => {
  console.log(e)
  const value = e.value
  switch (value) {
    case PayTypeEnum.WXPAY:
      paymentType.value = PayTypeEnum.WXPAY
      break
    case PayTypeEnum.ALIPAY:
      paymentType.value = PayTypeEnum.ALIPAY
      break
    case PayTypeEnum.BALANCE:
      paymentType.value = PayTypeEnum.BALANCE
      break
    default:
      console.warn('无效的支付类型')
      break
  }
}
</script>

<template>
  <view class="order-confirm">
    <!-- 地址栏 -->
    <view class="address-section" @click="openAddressPicker">
      <view class="address-card" v-if="defaultAddress">
        <view class="flex justify-between">
          <view>
            <text class="title">{{ defaultAddress.fullAddress + defaultAddress.address }}</text>
            <view class="address-info">
              <text class="text">{{ defaultAddress.name }}</text>
              <text class="text">{{ defaultAddress.phone }}</text>
            </view>
          </view>
          <view class="flex justify-center items-center">
            <wd-icon name="arrow-right" size="14px" color="#999" />
          </view>
        </view>
      </view>
      <view class="address-card" v-else>
        <view class="flex justify-between" @click="openAddressPicker">
          <view style="font-size: 36rpx">请选择收货地址</view>
          <wd-icon name="arrow-right" size="14px" color="#999" />
        </view>
      </view>
    </view>

    <!-- 商品清单 -->
    <view class="goods-section">
      <view class="section-title">商品清单（{{ goodsList.length }}）</view>
      <view class="goods-list">
        <view
          v-for="(item, index) in showAll ? goodsList : goodsList.slice(0, 3)"
          :key="item.id"
          class="goods-item"
        >
          <image
            :src="item.thumbImg"
            class="goods-thumb"
            @click="goGoodsInfo(item.goodsId, item.skuId)"
          />
          <view class="goods-info">
            <view class="goods-info-one">
              <text class="name">{{ item.skuName }}</text>
              <view class="goods-info-price">
                <text class="sale-price">{{ item.salePrice }}</text>
                <text class="market-price">{{ item.marketPrice }}</text>
              </view>
            </view>

            <text class="quantity">x{{ item.goodsNum }}</text>
          </view>
        </view>
      </view>

      <!-- 展开按钮 -->
      <view v-if="goodsList.length > 3" class="expand-btn" @click="showAll = !showAll">
        {{ showAll ? '收起' : '展开更多' }}
        <wd-icon :name="showAll ? 'arrow-up' : 'arrow-down'" />
      </view>
      <wd-divider></wd-divider>
      <!-- 优惠信息 -->
      <view class="discount-info">
        <view class="discount-item">
          <view>
            <text class="iconfont icon-cuxiao" style="margin-right: 10rpx"></text>
            <text>促销优惠</text>
          </view>
          <text class="value">-¥{{ formatMoney(marketTotalPrice - originalTotalPrice) }}</text>
        </view>
        <view class="discount-item">
          <view>
            <text class="iconfont icon-diyongquan" style="margin-right: 10rpx"></text>
            <text>优惠券</text>
          </view>
          <text class="value">-¥{{ discountTotalPrice }}</text>
        </view>
        <view class="total-line">
          <text>
            已优惠 ¥{{ formatMoney(discountTotalPrice + marketTotalPrice - originalTotalPrice) }}
          </text>
          <text class="total">合计：¥{{ totalPrice }}</text>
        </view>
      </view>
    </view>

    <!-- 支付方式 -->
    <!-- <view class="payment-section">
      <view class="section-title">支付方式</view>
      <wd-radio-group v-model="paymentType" checked-color="#ff5f15" shape="dot">
        <view class="payment-option">
          <wd-radio :value="PayTypeEnum.BALANCE" style="width: 100%">
            <view class="left">
              <view style="font-size: 42rpx" class="icon-balance iconfont"></view>
              <text style="font-size: 28rpx">余额</text>
            </view>
          </wd-radio>
        </view>
        <view class="payment-option">
          <wd-radio :value="PayTypeEnum.ALIPAY" style="width: 100%">
            <view class="left">
              <view style="font-size: 54rpx" class="icon-zhifubaozhifu iconfont"></view>
              <text style="font-size: 28rpx">支付宝</text>
            </view>
          </wd-radio>
        </view>
        <view class="payment-option">
          <wd-radio :value="PayTypeEnum.WXPAY" style="width: 100%">
            <view class="left">
              <view style="font-size: 42rpx" class="icon-zhifu-weixinzhifu iconfont"></view>
              <text style="font-size: 28rpx">微信</text>
            </view>
          </wd-radio>
        </view>
      </wd-radio-group>
    </view> -->
    <PayMent :payment-type="paymentType" @update:paymentType="updatePayment" />
    <!-- 留言备注 -->
    <view class="remark-section">
      <view class="section-title">留言备注</view>
      <wd-input
        v-model="remark"
        placeholder="请输入备注信息（50字以内）"
        :maxlength="50"
        clearable
      />
    </view>

    <!-- 底部操作栏 -->
    <CartBar
      model-type="pay"
      bottom="0"
      :cart-list="activeCartStore.cartItems"
      :discount-list="discountList"
      @submit-order="handleSubmit"
      :model-value="cartBarShow"
    />
    <AddressPicker ref="addressPicker" @select="onAddressSelect" @close="colseAddress" />
  </view>
</template>
<style lang="scss" scoped>
.order-confirm {
  padding: 20rpx;
  padding-bottom: 120rpx;
  background-color: #f5f5f5;
  background-image: linear-gradient(to bottom, #ff5f15 0%, #f5f5f5 100%);
  background-repeat: no-repeat;
  background-size: 100% 600rpx;
}

.address-section {
  padding: 30rpx;
  background: #fff;
  border-radius: 16rpx;
  .address-card {
    padding: 20rpx;

    .title {
      font-size: 32rpx;
      font-weight: bold;
      color: #333;
    }

    .address-info {
      margin-top: 20rpx;
      font-size: 24rpx;
      color: #999;
      p {
        margin-right: 30rpx;
        margin-bottom: 20rpx;
        font-size: 28rpx;
        background: #fff666;
      }
    }
  }
}
.section-title {
  margin-bottom: 20rpx;
  font-size: 32rpx;
  font-weight: 600;
  color: #333;
}
.goods-section {
  padding: 30rpx;
  margin: 20rpx 0;
  background: #fff;
  border-radius: 16rpx;

  .goods-list {
    .goods-item {
      display: flex;
      align-items: center;
      padding: 20rpx 0;
      border-bottom: 1rpx solid #eee;

      &:last-child {
        border: none;
      }

      .goods-thumb {
        width: 120rpx;
        height: 120rpx;
        margin-right: 20rpx;
        border-radius: 8rpx;
      }

      .goods-info {
        flex: 1;
        width: 220rpx;
        .goods-info-one {
          display: flex;
          justify-content: space-between;
          .goods-info-price {
            display: flex;
            flex-direction: column;
            .sale-price {
              padding-right: 20rpx;
              font-size: 28rpx;
              font-weight: 600;
              color: #333;
              &::before {
                font-size: 20rpx;
                content: '￥';
              }
            }
            .market-price {
              padding-right: 20rpx;
              font-size: 22rpx;
              color: #999;
              text-decoration: line-through;
              &::before {
                font-size: 20rpx;
                content: '￥';
              }
            }
          }
        }
        .name {
          display: -webkit-box;
          width: 300rpx;
          overflow: hidden;
          font-size: 28rpx;
          color: #666;
          text-overflow: ellipsis;
          -webkit-line-clamp: 2;
          -webkit-box-orient: vertical;
        }

        .quantity {
          font-size: 24rpx;
          color: #666;
        }
      }
    }
  }

  .expand-btn {
    padding: 20rpx;
    font-size: 28rpx;
    color: #999;
    text-align: center;
  }

  .discount-info {
    margin-top: 30rpx;

    .discount-item {
      display: flex;
      justify-content: space-between;
      padding: 15rpx 0;
      font-size: 28rpx;
      color: #666;

      .value {
        font-size: 32rpx;
        color: #e4393c;
      }
    }

    .total-line {
      display: flex;
      justify-content: space-between;
      padding-top: 20rpx;
      margin-top: 20rpx;
      border-top: 1rpx solid #eee;

      .total {
        margin-bottom: 20rpx;
        font-size: 32rpx;
        color: #e4393c;
      }
    }
  }
}

.action-footer {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 30rpx;
  background: #fff;
  box-shadow: 0 -4rpx 12rpx rgba(0, 0, 0, 0.05);

  .total-price {
    .amount {
      font-size: 36rpx;
      color: #e4393c;
    }
  }

  .submit-btn {
    width: 300rpx;
    border-radius: 50rpx;
  }
}

.remark-section {
  align-items: center;
  padding: 30rpx;
  margin: 20rpx 0;
  background-color: #fff;
  border-radius: 16rpx;
}
</style>
